﻿using CPF.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace CPFUI.IControl
{


    internal sealed class UnsafeNativeMethods
    {

        /// <summary>
        /// Retrieve a handle to the foreground window.
        /// 检索到前台窗口的句柄
        /// http://msdn.microsoft.com/en-us/library/ms633505(VS.85).aspx
        /// </summary>
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr GetForegroundWindow();

        /// <summary>
        /// Bring the thread that created the specified window into the foreground
        /// and activates the window. 
        /// 带来的线程创建指定窗口到前台，并激活窗口。
        /// http://msdn.microsoft.com/en-us/library/ms633539(VS.85).aspx
        /// </summary>
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        /// <summary>
        /// Determine whether the specified window handle identifies an existing window. 
        /// 确定是否在指定的窗口句柄标识现有的窗口。
        /// http://msdn.microsoft.com/en-us/library/ms633528(VS.85).aspx
        /// </summary>
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool IsWindow(IntPtr hWnd);
        /// <summary>
        /// Retrieves the status of the specified virtual key. The status specifies whether
        /// the key is up, down, or toggled (on, off—alternating each time the key is pressed).
        /// http://msdn.microsoft.com/en-us/library/ms646301(VS.85).aspx
        /// </summary>
        /// <param name="nVirtKey">A virtual key. </param>
        /// <returns>
        /// If the high-order bit is 1, the key is down; otherwise, it is up.
        /// If the low-order bit is 1, the key is toggled. A key, such as the CAPS LOCK key,
        /// is toggled if it is turned on. The key is off and untoggled if the low-order bit
        /// is 0. A toggle key's indicator light (if any) on the keyboard will be on when the
        /// key is toggled, and off when the key is untoggled.
        /// </returns>
        [DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern short GetKeyState(int nVirtKey);

        /// <summary>
        /// Synthesizes keystrokes, mouse motions, and button clicks.
        /// http://msdn.microsoft.com/en-us/library/ms646310(VS.85).aspx
        /// </summary>
        /// <param name="nInputs">The number of structures in the pInputs array.</param>
        /// <param name="pInputs">
        /// An array of INPUT structures. Each structure represents an event to be inserted 
        /// into the keyboard or mouse input stream.
        /// </param>
        /// <param name="cbSize">
        /// The size, in bytes, of an INPUT structure. If cbSize is not the size of an 
        /// INPUT structure, the function fails.
        /// </param>
        /// <returns>
        /// If the function returns zero, the input was already blocked by another thread. 
        /// </returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern uint SendInput(uint nInputs, NativeMethods.INPUT[] pInputs, int cbSize);
        [DllImport("user32.dll")]
        public static extern IntPtr GetMessageExtraInfo();
        [DllImport("user32.dll")]
        public static extern int GetKeyboardLayoutList(int nBuff, IntPtr[] lpList);

        [DllImport("user32.dll")]
        public static extern int GetKeyboardLayoutName(StringBuilder pwszKLID, int cchKLID);

        // 导入user32.dll库文件
        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
        public const int WM_INPUTLANGCHANGEREQUEST = 0x50;
        public const int INPUTLANGCHANGE_FORWARD = 1;

        [DllImport("imm32.dll")]
        public static extern IntPtr ImmSetActiveContext(IntPtr himc, IntPtr himcNew);

        [DllImport("imm32.dll")]
        public static extern IntPtr ImmGetContext(IntPtr hwnd);

        [DllImport("imm32.dll")]
        public static extern bool ImmReleaseContext(IntPtr hwnd, IntPtr himc);

        // 这里的GUID是示例，需要替换为你想要设置的IME的GUID
        private static readonly Guid IME_GUID = new Guid("你的IME GUID");

        public static void SetActiveIMEProfile()
        {
            
            IntPtr hwnd =GetForegroundWindow(); // 获取你的应用程序的句柄
            IntPtr himc = ImmGetContext(hwnd);
            if (himc != IntPtr.Zero)
            {
                // 设置输入法上下文
                ImmSetActiveContext(hwnd, himc);
                ImmReleaseContext(hwnd, himc);
            }
        }
        [DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
        public static extern int PostMessage(IntPtr hWnd, int Msg, Keys wParam, int lParam);
        [DllImport("user32.dll", SetLastError = true)]
        public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

        public const byte VK_LSHIFT = 0xA0; // 左Shift键的虚拟键码
        public const byte VK_RSHIFT = 0xA1; // 右Shift键的虚拟键码

        public const int WM_KEYDOWN = 0x100;
        public const int WM_KEYUP = 0x101;

        public const int KEYEVENTF_EXTENDEDKEY = 0x1;
        public const int KEYEVENTF_KEYUP = 0x2;

        public static void SimulateShiftKeyPress(IntPtr hw)
        {
            SendMessage(hw, WM_KEYDOWN, (IntPtr)Keys.ShiftKey, IntPtr.Zero);
            SendMessage(hw, WM_KEYUP, (IntPtr)Keys.ShiftKey, IntPtr.Zero);
        }
    }
}
